Skip to content

feat(databasesql): add DSN parser registry with extensibility and tests.#509

Open
karthik120710 wants to merge 4 commits into
open-telemetry:mainfrom
karthik120710:issue#508
Open

feat(databasesql): add DSN parser registry with extensibility and tests.#509
karthik120710 wants to merge 4 commits into
open-telemetry:mainfrom
karthik120710:issue#508

Conversation

@karthik120710
Copy link
Copy Markdown

Summary

  • Replaced the hardcoded switch in parseDSN with a sync.RWMutex-protected registry of DSNParser functions, making the DSN parsing layer pluggable
    without modifying core code.
  • Added RegisterDSNParser(driverName, parser) as a public API so external drivers and future integrations can register their own parsers (e.g., from
    init()).
  • Registered all previously hardcoded drivers at init() time, including newly added aliases: pgx, lib/pq, sqlserver, oracle, go-oci8, and oci8.
  • Added a bestEffortParse fallback (standard URL parsing) for unrecognized drivers, replacing the prior silent empty-address behavior.
  • Added a Warn log when DSN parsing fails so server.address omission is surfaced rather than silently emitted as "unknown".
  • Expanded DbClientRequestTraceAttrs system-name mapping to cover mariadb, pgx, lib/pq, clickhouse, oracle, and mssql/sqlserver — previously these all
    fell through to other_sql.
  • Bumped go.opentelemetry.io/otel/log, sdk/log, and related packages to v0.19.0.
  • Added a test case for the clickhouse driver system-name mapping and a separate case confirming unknown drivers fall back to other_sql.

Test plan

  • Run go test ./pkg/instrumentation/databasesql/... — all existing and new semconv tests pass.
  • Verify a custom driver can be registered via RegisterDSNParser in an init() and is correctly used at hook time.
  • Confirm that an unregistered driver with a standard URL DSN gets a best-effort address instead of an empty string.
  • Confirm a warning is logged when DSN parsing fails.
    DSN parser lacks extensibility and silently produces empty addresses for unknown drivers #508

- Added a custom DSN parser registration mechanism to support various database drivers.
- Implemented a fallback parsing method for unregistered drivers, improving robustness.
- Updated logging to warn when the server address cannot be determined from the DSN.
- Enhanced test cases to cover new parsing logic and driver mappings.

This change improves the flexibility and reliability of database connection handling.

Signed-off-by: Karthik Rajan <karthikrajanmr@gmail.com>
@karthik120710 karthik120710 requested a review from a team as a code owner May 15, 2026 19:06
@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla Bot commented May 15, 2026

CLA Signed
The committers listed above are authorized under a signed CLA.

  • ✅ login: karthik120710 / name: Karthik Rajan (b628582)

@github-actions
Copy link
Copy Markdown

The title of this pull request does not match the conventional commits format.
Please update the title, as apprioriate.

Refer to the CONTRIBUTING.md file for more information.

@karthik120710 karthik120710 changed the title replace hardcoded DSN switch with extensible parser registry [instrumentation/databasesql] replace hardcoded DSN switch with extensible parser registry May 16, 2026
@github-actions
Copy link
Copy Markdown

The title of this pull request does not match the conventional commits format.
Please update the title, as apprioriate.

Refer to the CONTRIBUTING.md file for more information.

@karthik120710 karthik120710 changed the title [instrumentation/databasesql] replace hardcoded DSN switch with extensible parser registry fix(instrumentation/databasesql): add pluggable DSN parser registry and expand semconv driver mapping May 16, 2026
@github-actions
Copy link
Copy Markdown

The title of this pull request does not match the conventional commits format.
Please update the title, as apprioriate.

Refer to the CONTRIBUTING.md file for more information.

@karthik120710
Copy link
Copy Markdown
Author

hi @txabman42 i have added pluggable DSN parser registry and expand semconv driver mapping can u review my pr.

@waqar2403
Copy link
Copy Markdown

Hey @karthik120710, nice work a few things I noticed while going through the diff

Build issue: The refactor removes ParseDbName from parse.go but client.go:47 still calls it (dbName := ParseDbName(dataSourceName)). This would fail to compile. Was the removal accidental during the registry refactor?

Test coverage: The new tests cover the semconv mapping changes (clickhouse, unknown driver) but there are no tests for RegisterDSNParser itself, bestEffortParse, or the new aliases like pgx and lib/pq going through parsePostgres. Since the registry is the main change here, a basic test showing registration and lookup works would help.

Minor: The PR title has a leading space which is causing the conventional commit check to fail. Trimming it should fix the CI.

@karthik120710 karthik120710 changed the title fix(instrumentation/databasesql): add pluggable DSN parser registry and expand semconv driver mapping feat(databasesql): add DSN parser registry with extensibility and tests. May 16, 2026
@github-actions github-actions Bot added the scope:feat A new feature being added label May 16, 2026
…verage

- Refactored DSN parsing logic to utilize a dedicated internal package for improved organization and maintainability.
- Renamed functions for consistency and clarity, specifically changing  to .
- Added comprehensive unit tests for the new parsing logic, ensuring robust handling of various DSN formats and edge cases.

This update enhances the overall structure of the codebase and improves the reliability of database connection handling.

Signed-off-by: Karthik Rajan <karthikrajanmr@gmail.com>
@karthik120710
Copy link
Copy Markdown
Author

Hi @waqar2403 I have add units test and updated process title , but still unit test are not running .

@waqar2403
Copy link
Copy Markdown

@karthik120710 good progress on the registry refactoring. Two things here:

Tests not running Your go.mod bumps a few OTel indirect deps (otlploghttp, otel/log, sdk/log) but the go.sum likely needs regeneration. Try this from the module root:

cd pkg/instrumentation/databasesql
go mod tidy
go test ./

If there are still import resolution errors after that, check if testify is listed under require in your go.mod it should already be there from the existing db_test.go usage.

Minor style note on RegisterDSNParse Right now RegisterDSNParser is exposed as a mutable variable

var RegisterDSNParser = dsnparse.RegisterDSNParser

This means any consumer can accidentally overwrite it like db.RegisterDSNParser = nil A simple wrapper function removes that risk

func RegisterDSNParser(driverName string, parser dsnparse.DSNParser) {
    dsnparse.RegisterDSNParser(driverName, parser)
}

Not a blocker just something to consider for safety.
Otherwise the internal/dsnparse package structure, the registry with sync.RWMutex, the BestEffortParse fallback, and the new semconv driver mappings all look good to me.

- Introduced a wrapper function for  to maintain consistency in the registration process.
- This change enhances the clarity of the parser registration mechanism while preserving existing functionality.

This update contributes to better code organization and maintainability in the DSN parsing logic.

Signed-off-by: Karthik Rajan <karthikrajanmr@gmail.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 19, 2026

📊 Semantic Convention Registry Update Check

Current Project Version: v1.37.0 (from .semconv-version)

ℹ️ This is a non-blocking informational check that shows what semantic convention updates are available. It helps you stay informed about new conventions without requiring immediate action.

🆕 Available Updates

Comparing latest (main branch) vs v1.37.0 (current)

💡 New semantic conventions are available. Consider updating if these changes are relevant to your instrumentation:

📋 View available updates

Summary of Schema Changes

Registry versions

Baseline: unversioned

Head: unversioned

Registry Attributes

Added

  • app.screen.id
  • app.screen.name
  • browser.document.url.full
  • feature_flag.error.message
  • gcp.apphub_destination.application.container
  • gcp.apphub_destination.application.id
  • gcp.apphub_destination.application.location
  • gcp.apphub_destination.service.criticality_type
  • gcp.apphub_destination.service.environment_type
  • gcp.apphub_destination.service.id
  • gcp.apphub_destination.workload.criticality_type
  • gcp.apphub_destination.workload.environment_type
  • gcp.apphub_destination.workload.id
  • gcp.gce.instance.labels
  • gcp.gce.instance_group_manager.name
  • gcp.gce.instance_group_manager.region
  • gcp.gce.instance_group_manager.zone
  • gen_ai.agent.version
  • gen_ai.embeddings.dimension.count
  • gen_ai.evaluation.explanation
  • gen_ai.evaluation.name
  • gen_ai.evaluation.score.label
  • gen_ai.evaluation.score.value
  • gen_ai.prompt.name
  • gen_ai.request.stream
  • gen_ai.response.time_to_first_chunk
  • gen_ai.retrieval.documents
  • gen_ai.retrieval.query.text
  • gen_ai.tool.call.arguments
  • gen_ai.tool.call.result
  • gen_ai.tool.definitions
  • gen_ai.usage.cache_creation.input_tokens
  • gen_ai.usage.cache_read.input_tokens
  • gen_ai.usage.reasoning.output_tokens
  • gen_ai.workflow.name
  • go.cpu.detailed_state
  • go.cpu.state
  • go.memory.detailed_type
  • jsonrpc.protocol.version
  • jsonrpc.request.id
  • k8s.container.ephemeral_storage.fs_type
  • k8s.node.system_container.name
  • k8s.persistentvolume.annotation
  • k8s.persistentvolume.label
  • k8s.persistentvolume.name
  • k8s.persistentvolume.reclaim_policy
  • k8s.persistentvolume.status.phase
  • k8s.persistentvolume.uid
  • k8s.persistentvolumeclaim.annotation
  • k8s.persistentvolumeclaim.label
  • k8s.persistentvolumeclaim.name
  • k8s.persistentvolumeclaim.status.phase
  • k8s.persistentvolumeclaim.uid
  • k8s.pod.hostname
  • k8s.pod.ip
  • k8s.pod.start_time
  • k8s.pod.status.phase
  • k8s.pod.status.reason
  • k8s.service.annotation
  • k8s.service.endpoint.address_type
  • k8s.service.endpoint.condition
  • k8s.service.endpoint.zone
  • k8s.service.label
  • k8s.service.name
  • k8s.service.publish_not_ready_addresses
  • k8s.service.selector
  • k8s.service.traffic_distribution
  • k8s.service.type
  • k8s.service.uid
  • mcp.method.name
  • mcp.protocol.version
  • mcp.resource.uri
  • mcp.session.id
  • nfs.operation.name
  • nfs.server.repcache.status
  • onc_rpc.procedure.name
  • onc_rpc.procedure.number
  • onc_rpc.program.name
  • onc_rpc.version
  • openai.api.type
  • openshift.clusterquota.name
  • openshift.clusterquota.uid
  • oracle.db.domain
  • oracle.db.instance.name
  • oracle.db.name
  • oracle.db.pdb
  • oracle.db.service
  • oracle_cloud.realm
  • otel.event.name
  • pprof.location.is_folded
  • pprof.mapping.has_filenames
  • pprof.mapping.has_functions
  • pprof.mapping.has_inline_frames
  • pprof.mapping.has_line_numbers
  • pprof.profile.comment
  • pprof.profile.doc_url
  • pprof.profile.drop_frames
  • pprof.profile.keep_frames
  • pprof.scope.default_sample_type
  • pprof.scope.sample_type_order
  • process.context_switch.type
  • process.state
  • rpc.method_original
  • rpc.request.metadata
  • rpc.response.metadata
  • rpc.response.status_code
  • rpc.system.name
  • service.criticality
  • service.peer.name
  • service.peer.namespace
  • system.memory.linux.hugepages.state
  • system.memory.linux.slab.state
  • system.paging.fault.type
  • v8js.resource.type

Renamed

  • process.paging.fault_type --> system.paging.fault.type (Note: Replaced by system.paging.fault.type.)
  • rpc.jsonrpc.request_id --> jsonrpc.request.id (Note: Replaced by jsonrpc.request.id.)
  • rpc.jsonrpc.version --> jsonrpc.protocol.version (Note: Replaced by jsonrpc.protocol.version.)
  • system.paging.type --> system.paging.fault.type (Note: Replaced by system.paging.fault.type.)
  • process.context_switch_type --> process.context_switch.type (Note: Replaced by process.context_switch.type.)
  • rpc.grpc.request.metadata --> rpc.request.metadata (Note: Replaced by rpc.request.metadata.)
  • rpc.grpc.response.metadata --> rpc.response.metadata (Note: Replaced by rpc.response.metadata.)
  • rpc.connect_rpc.error_code --> rpc.response.status_code (Note: Replaced by rpc.response.status_code.)
  • linux.memory.slab.state --> system.memory.linux.slab.state (Note: Replaced by system.memory.linux.slab.state.)
  • feature_flag.evaluation.error.message --> feature_flag.error.message (Note: Replaced by feature_flag.error.message.)
  • rpc.connect_rpc.request.metadata --> rpc.request.metadata (Note: Replaced by rpc.request.metadata.)
  • rpc.system --> rpc.system.name (Note: Replaced by rpc.system.name.)
  • peer.service --> service.peer.name (Note: Replaced by service.peer.name.)
  • system.processes.status --> process.state (Note: Replaced by process.state.)
  • system.process.status --> process.state (Note: Replaced by process.state.)
  • rpc.connect_rpc.response.metadata --> rpc.response.metadata (Note: Replaced by rpc.response.metadata.)
  • system.cpu.logical_number --> cpu.logical_number (Note: Replaced by cpu.logical_number.)

Obsoleted

  • error.message (Note: Use domain-specific error message attribute. For example, use feature_flag.error.message for feature flag errors.)
  • message.compressed_size (Note: Deprecated, no replacement at this time.)
  • message.id (Note: Deprecated, no replacement at this time.)
  • message.type (Note: Deprecated, no replacement at this time.)
  • message.uncompressed_size (Note: Deprecated, no replacement at this time.)
  • rpc.message.compressed_size (Note: Deprecated, no replacement at this time.)
  • rpc.message.id (Note: Deprecated, no replacement at this time.)
  • rpc.message.type (Note: Deprecated, no replacement at this time.)
  • rpc.message.uncompressed_size (Note: Deprecated, no replacement at this time.)

Uncategorized

Metrics

Added

  • container.memory.available
  • container.memory.paging.faults
  • container.memory.rss
  • container.memory.working_set
  • gen_ai.client.operation.time_per_output_chunk
  • gen_ai.client.operation.time_to_first_chunk
  • go.cpu.time
  • go.memory.gc.cycles
  • go.memory.gc.pause.duration
  • jvm.file_descriptor.limit
  • k8s.container.cpu.limit.current
  • k8s.container.cpu.limit.desired
  • k8s.container.cpu.limit.utilization
  • k8s.container.cpu.limit_utilization
  • k8s.container.cpu.request.current
  • k8s.container.cpu.request.desired
  • k8s.container.cpu.request.utilization
  • k8s.container.cpu.request_utilization
  • k8s.container.ephemeral_storage.usage
  • k8s.container.memory.limit.current
  • k8s.container.memory.limit.desired
  • k8s.container.memory.request.current
  • k8s.container.memory.request.desired
  • k8s.cronjob.job.active
  • k8s.daemonset.node.current_scheduled
  • k8s.daemonset.node.desired_scheduled
  • k8s.daemonset.node.misscheduled
  • k8s.daemonset.node.ready
  • k8s.deployment.pod.available
  • k8s.deployment.pod.desired
  • k8s.hpa.pod.current
  • k8s.hpa.pod.desired
  • k8s.hpa.pod.max
  • k8s.hpa.pod.min
  • k8s.job.pod.active
  • k8s.job.pod.desired_successful
  • k8s.job.pod.failed
  • k8s.job.pod.max_parallel
  • k8s.job.pod.successful
  • k8s.node.cpu.allocatable
  • k8s.node.ephemeral_storage.allocatable
  • k8s.node.memory.allocatable
  • k8s.node.memory.available
  • k8s.node.memory.paging.faults
  • k8s.node.memory.rss
  • k8s.node.memory.working_set
  • k8s.node.pod.allocatable
  • k8s.node.system_container.cpu.time
  • k8s.node.system_container.cpu.usage
  • k8s.node.system_container.memory.usage
  • k8s.node.system_container.memory.working_set
  • k8s.persistentvolume.status.phase
  • k8s.persistentvolume.storage.capacity
  • k8s.persistentvolumeclaim.status.phase
  • k8s.persistentvolumeclaim.storage.capacity
  • k8s.persistentvolumeclaim.storage.request
  • k8s.pod.memory.available
  • k8s.pod.memory.paging.faults
  • k8s.pod.memory.rss
  • k8s.pod.memory.working_set
  • k8s.pod.status.phase
  • k8s.pod.status.reason
  • k8s.replicaset.pod.available
  • k8s.replicaset.pod.desired
  • k8s.replicationcontroller.pod.available
  • k8s.replicationcontroller.pod.desired
  • k8s.service.endpoint.count
  • k8s.service.load_balancer.ingress.count
  • k8s.statefulset.pod.current
  • k8s.statefulset.pod.desired
  • k8s.statefulset.pod.ready
  • k8s.statefulset.pod.updated
  • mcp.client.operation.duration
  • mcp.client.session.duration
  • mcp.server.operation.duration
  • mcp.server.session.duration
  • nfs.client.net.count
  • nfs.client.net.tcp.connection.accepted
  • nfs.client.operation.count
  • nfs.client.procedure.count
  • nfs.client.rpc.authrefresh.count
  • nfs.client.rpc.count
  • nfs.client.rpc.retransmit.count
  • nfs.server.fh.stale.count
  • nfs.server.io
  • nfs.server.net.count
  • nfs.server.net.tcp.connection.accepted
  • nfs.server.operation.count
  • nfs.server.procedure.count
  • nfs.server.repcache.requests
  • nfs.server.rpc.count
  • nfs.server.thread.count
  • openshift.clusterquota.cpu.limit.hard
  • openshift.clusterquota.cpu.limit.used
  • openshift.clusterquota.cpu.request.hard
  • openshift.clusterquota.cpu.request.used
  • openshift.clusterquota.ephemeral_storage.limit.hard
  • openshift.clusterquota.ephemeral_storage.limit.used
  • openshift.clusterquota.ephemeral_storage.request.hard
  • openshift.clusterquota.ephemeral_storage.request.used
  • openshift.clusterquota.hugepage_count.request.hard
  • openshift.clusterquota.hugepage_count.request.used
  • openshift.clusterquota.memory.limit.hard
  • openshift.clusterquota.memory.limit.used
  • openshift.clusterquota.memory.request.hard
  • openshift.clusterquota.memory.request.used
  • openshift.clusterquota.object_count.hard
  • openshift.clusterquota.object_count.used
  • openshift.clusterquota.persistentvolumeclaim_count.hard
  • openshift.clusterquota.persistentvolumeclaim_count.used
  • openshift.clusterquota.storage.request.hard
  • openshift.clusterquota.storage.request.used
  • process.unix.file_descriptor.count
  • process.windows.handle.count
  • rpc.client.call.duration
  • rpc.server.call.duration
  • system.memory.linux.available
  • system.memory.linux.hugepages.limit
  • system.memory.linux.hugepages.page_size
  • system.memory.linux.hugepages.reserved
  • system.memory.linux.hugepages.surplus
  • system.memory.linux.hugepages.usage
  • system.memory.linux.hugepages.utilization
  • system.memory.linux.shared
  • system.memory.linux.slab.usage
  • system.network.dropped
  • system.network.packets
  • v8js.memory.heap.space.available_size
  • v8js.memory.heap.space.physical_size
  • v8js.memory.heap.space.size
  • v8js.resource.active

Renamed

  • k8s.job.failed_pods --> k8s.job.pod.failed (Note: Replaced by k8s.job.pod.failed.)
  • k8s.replication_controller.available_pods --> k8s.replicationcontroller.pod.available (Note: Replaced by k8s.replicationcontroller.pod.available.)
  • k8s.replicaset.desired_pods --> k8s.replicaset.pod.desired (Note: Replaced by k8s.replicaset.pod.desired.)
  • v8js.heap.space.physical_size --> v8js.memory.heap.space.physical_size (Note: Replaced by v8js.memory.heap.space.physical_size.)
  • k8s.container.memory.limit --> k8s.container.memory.limit.desired (Note: Replaced by k8s.container.memory.limit.desired.)
  • k8s.replication_controller.desired_pods --> k8s.replicationcontroller.pod.desired (Note: Replaced by k8s.replicationcontroller.pod.desired.)
  • k8s.hpa.current_pods --> k8s.hpa.pod.current (Note: Replaced by k8s.hpa.pod.current.)
  • k8s.deployment.available_pods --> k8s.deployment.pod.available (Note: Replaced by k8s.deployment.pod.available.)
  • system.memory.shared --> system.memory.linux.shared (Note: Replaced by system.memory.linux.shared.)
  • k8s.statefulset.desired_pods --> k8s.statefulset.pod.desired (Note: Replaced by k8s.statefulset.pod.desired.)
  • k8s.replicaset.available_pods --> k8s.replicaset.pod.available (Note: Replaced by k8s.replicaset.pod.available.)
  • k8s.job.max_parallel_pods --> k8s.job.pod.max_parallel (Note: Replaced by k8s.job.pod.max_parallel.)
  • k8s.daemonset.misscheduled_nodes --> k8s.daemonset.node.misscheduled (Note: Replaced by k8s.daemonset.node.misscheduled.)
  • k8s.replicationcontroller.desired_pods --> k8s.replicationcontroller.pod.desired (Note: Replaced by k8s.replicationcontroller.pod.desired.)
  • k8s.daemonset.desired_scheduled_nodes --> k8s.daemonset.node.desired_scheduled (Note: Replaced by k8s.daemonset.node.desired_scheduled.)
  • k8s.hpa.min_pods --> k8s.hpa.pod.min (Note: Replaced by k8s.hpa.pod.min.)
  • k8s.node.allocatable.pods --> k8s.node.pod.allocatable (Note: Replaced by k8s.node.pod.allocatable.)
  • k8s.node.allocatable.cpu --> k8s.node.cpu.allocatable (Note: Replaced by k8s.node.cpu.allocatable.)
  • k8s.daemonset.ready_nodes --> k8s.daemonset.node.ready (Note: Replaced by k8s.daemonset.node.ready.)
  • k8s.statefulset.current_pods --> k8s.statefulset.pod.current (Note: Replaced by k8s.statefulset.pod.current.)
  • k8s.cronjob.active_jobs --> k8s.cronjob.job.active (Note: Replaced by k8s.cronjob.job.active.)
  • k8s.deployment.desired_pods --> k8s.deployment.pod.desired (Note: Replaced by k8s.deployment.pod.desired.)
  • k8s.node.allocatable.memory --> k8s.node.memory.allocatable (Note: Replaced by k8s.node.memory.allocatable.)
  • k8s.node.allocatable.ephemeral_storage --> k8s.node.ephemeral_storage.allocatable (Note: Replaced by k8s.node.ephemeral_storage.allocatable.)
  • process.open_file_descriptor.count --> process.unix.file_descriptor.count (Note: Replaced by process.unix.file_descriptor.count.)
  • system.linux.memory.available --> system.memory.linux.available (Note: Replaced by system.memory.linux.available.)
  • k8s.job.successful_pods --> k8s.job.pod.successful (Note: Replaced by k8s.job.pod.successful.)
  • v8js.heap.space.available_size --> v8js.memory.heap.space.available_size (Note: Replaced by v8js.memory.heap.space.available_size.)
  • system.linux.memory.slab.usage --> system.memory.linux.slab.usage (Note: Replaced by system.memory.linux.slab.usage.)
  • k8s.hpa.max_pods --> k8s.hpa.pod.max (Note: Replaced by k8s.hpa.pod.max.)
  • k8s.daemonset.current_scheduled_nodes --> k8s.daemonset.node.current_scheduled (Note: Replaced by k8s.daemonset.node.current_scheduled.)
  • k8s.job.active_pods --> k8s.job.pod.active (Note: Replaced by k8s.job.pod.active.)
  • k8s.hpa.desired_pods --> k8s.hpa.pod.desired (Note: Replaced by k8s.hpa.pod.desired.)
  • k8s.statefulset.updated_pods --> k8s.statefulset.pod.updated (Note: Replaced by k8s.statefulset.pod.updated.)
  • k8s.job.desired_successful_pods --> k8s.job.pod.desired_successful (Note: Replaced by k8s.job.pod.desired_successful.)
  • k8s.replicationcontroller.available_pods --> k8s.replicationcontroller.pod.available (Note: Replaced by k8s.replicationcontroller.pod.available.)
  • k8s.container.cpu.request --> k8s.container.cpu.request.desired (Note: Replaced by k8s.container.cpu.request.desired.)
  • k8s.statefulset.ready_pods --> k8s.statefulset.pod.ready (Note: Replaced by k8s.statefulset.pod.ready.)
  • k8s.container.cpu.limit --> k8s.container.cpu.limit.desired (Note: Replaced by k8s.container.cpu.limit.desired.)
  • k8s.container.memory.request --> k8s.container.memory.request.desired (Note: Replaced by k8s.container.memory.request.desired.)

Obsoleted

  • rpc.client.request.size (Note: Removed, no replacement at this time.)
  • rpc.client.requests_per_rpc (Note: Removed, no replacement at this time.)
  • rpc.client.response.size (Note: Removed, no replacement at this time.)
  • rpc.client.responses_per_rpc (Note: Removed, no replacement at this time.)
  • rpc.server.request.size (Note: Removed, no replacement at this time.)
  • rpc.server.requests_per_rpc (Note: Removed, no replacement at this time.)
  • rpc.server.response.size (Note: Removed, no replacement at this time.)
  • rpc.server.responses_per_rpc (Note: Removed, no replacement at this time.)

Uncategorized

Events

Added

  • db.client.operation.exception
  • faas.invocation.exception
  • gen_ai.client.operation.exception
  • gen_ai.evaluation.result
  • http.client.request.exception
  • http.server.request.exception
  • messaging.create.exception
  • messaging.process.exception
  • messaging.receive.exception
  • messaging.send.exception
  • messaging.settle.exception
  • rpc.client.call.exception
  • rpc.server.call.exception

Obsoleted

  • rpc.message (Note: Deprecated, no replacement at this time.)

Uncategorized


📝 What This Means

  • Non-blocking: This check will never fail your PR
  • Informational: Shows what's new in the semantic conventions
  • Optional: You can choose when to adopt new conventions

How to Update (if desired):

  1. Review the changes above to see if they're relevant to your use case
  2. Update Go imports in pkg/instrumentation/**/semconv/ to the new semconv version
  3. Update the version in .semconv-version file
  4. Run make registry-check locally to validate

Generated by OTel Weaver • Run make semantic-conventions/diff locally for details

@codecov
Copy link
Copy Markdown

codecov Bot commented May 19, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (main@3e45b48). Learn more about missing BASE report.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #509   +/-   ##
=======================================
  Coverage        ?   63.30%           
=======================================
  Files           ?       62           
  Lines           ?     4796           
  Branches        ?        0           
=======================================
  Hits            ?     3036           
  Misses          ?     1509           
  Partials        ?      251           
Flag Coverage Δ
pkg 63.30% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Member

@kakkoyun kakkoyun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the initiative.

This requires a bit of improvement. Please see my comments.

)

// DSNParser parses a driver-specific DSN and returns the server address (host:port).
type DSNParser func(dsn string) (addr string, err error)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I would prefer having an interface for parser, and implementations in struct.


var (
parserMu sync.RWMutex
parserRegistry = map[string]DSNParser{}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can have another struct type for registry and we don't need package level locks.


func init() {
// Register all built-in DSN parsers.
RegisterDSNParser("mysql", ParseMySQL)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are constantly locking and unlocking here. We can have a batch API where lock only once.


// BestEffortParse attempts to extract a host:port from a DSN using standard URL parsing.
// It is used as a fallback for drivers that have no registered parser.
func BestEffortParse(dsn string) (string, error) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to export this method.

// clickhouse://host:port/database?username=user&password=pass
u, err := nurl.Parse(dsn)
if err != nil {
return "", err
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't just return the net/url error here. It exposes the rawURL and it means we can leak the sensitive information to some external service if somebody tries to log or send the error.

See: https://cs.opensource.google/go/go/+/refs/tags/go1.26.3:src/net/url/url.go;l=398

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope:feat A new feature being added

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants